#Что такое  Deadlock?
# Ситуация, когда две задачи ожидают ресурсы, занятые друг другом, в результате чего обе останавливаются


# Какая стратегия может помочь предотвратить Deadlock при работе с несколькими блокировками?
# Захватывать блокировки в установленном порядке


# Какое решение позволяет избежать бесконечного ожидания в Deadlock ситуации?
# Использование таймаутов при ожидании

# Какой подход помогает предотвратить Deadlock при возникновении исключения в критической секции кода?
# Использование конструкции try/finally для гарантии освобождения ресурсов


# Какое из следующих утверждений верно относительно последствий Deadlock?
# Deadlock может привести к зависанию или замедлению программы

# Deadlock может привести к зависанию или замедлению программы
# Произвольный захват ресурсов без установленного порядка


# Какая практика НЕ способствует профилактике Deadlock в асинхронном коде?
# Использование неограниченного количества асинхронных блокировок

#Почему следующий код может не увеличить global_counter атомарно до 2 при асинхронном выполнении двух корутин?
# import asyncio

# global_counter = 0

# async def increment():
#     global global_counter
#     temp = global_counter
#     await asyncio.sleep(0.01)  # Имитация долгой операции
#     global_counter = temp + 1

# async def main():
#     await asyncio.gather(increment(), increment())

# asyncio.run(main())
# print(f"global_counter: {global_counter}")
# Примечание: Поскольку операция обновления global_counter разделена на чтение, имитацию долгой операции и запись,
# две корутины могут прочитать одно и то же значение global_counter до увеличения, что приводит к некорректному
# итоговому результату из-за отсутствия атомарности..

#Исходный код
# import asyncio

# global_counter = 0

# async def increment():
#     global global_counter
#     temp = global_counter
#     await asyncio.sleep(.01)
#     global_counter = temp + 2.39

# async def main():
#     await asyncio.gather(*[increment() for x in range(99)])

# asyncio.run(main())
# print(f"global_counter: {round(global_counter,2)}")

#Новый код
# import asyncio

# global_counter = 0

# async def increment(lock:asyncio.Lock):

#     global global_counter
#     async with lock:
#         temp = global_counter
#         await asyncio.sleep(.01)
#         global_counter = temp + 2.39

# async def main():
#     lock = asyncio.Lock()
#     await asyncio.gather(*[increment(lock) for _ in range(99)])

# asyncio.run(main())
# print(f"global_counter: {round(global_counter,2)}")
#Без контексного менеджера
import asyncio

global_counter = 0

async def increment(lock:asyncio.Lock):
    
    global global_counter
    
    await lock.acquire()
    try: 
        temp = global_counter
        await asyncio.sleep(.01)
        global_counter = temp + 2.39
    finally:
        lock.release()

async def main():
    lock = asyncio.Lock()
    await asyncio.gather(*[increment(lock) for _ in range(99)])

asyncio.run(main())
print(f"global_counter: {round(global_counter,2)}")

